#include <iostream>
#include<memory>
//单例模式-饿汉模式
// class Singleton
// {
//     public:
//    static Singleton& getInstance()
//     {
//         return eton_;
//     }
//     private:
//     static Singleton eton_;
// };
// Singleton Singleton::eton_;

//单例模式-懒汉模式
// class Singleton
// {
//     private:
//     Singleton(){}
//     ~Singleton(){}
//     public:
//     static Singleton&getInstance()
//     {
//        static Singleton eton_;
//        return eton_;
//     }
// };

//工厂模式
//简单工厂模式
// class Fruit
// {
//     public:
//     virtual void name()=0;
//     private:
// };
// class Apple : public Fruit
// {
//     private:
//     public:
//     void name()
//     {
//         std::cout<<"i am a apple!!"<<std::endl;
//     }

// };
// class Banana:public Fruit
// {
//     private:
//     public:
//     void name()
//     {
//         std::cout<<"i am a banana !!"<<std::endl;
//     }
// };

// class FruitFactory
// {
//     private:
//     public:
//     static std::shared_ptr<Fruit> create(const std::string& name)
//     {
//         if(name=="苹果")
//         {
//             return std::make_shared<Apple>();
//         }
//         else
//         {
//             return std::make_shared<Banana>();
//         }
//     }
// };

//工厂方法模式
// class Fruit
// {
//     public:
//     virtual void name()=0;
//     private:
// };
// class Apple : public Fruit
// {
//     private:
//     public:
//     void name()
//     {
//         std::cout<<"i am a apple!!"<<std::endl;
//     }

// };
// class Banana:public Fruit
// {
//     private:
//     public:
//     void name()
//     {
//         std::cout<<"i am a banana !!"<<std::endl;
//     }
// };

// class FruitFactory
// {
//     public:
//     virtual std::shared_ptr<Fruit> create()=0;
//     private:
// };
// class AppleFactory : public FruitFactory
// {
//     public:
//     std::shared_ptr<Fruit>create()override
//     {
//         return std::make_shared<Apple>();
//     }
//     private:
// };
// class BananaFactory : public FruitFactory
// {
//     public:
//     std::shared_ptr<Fruit>create()override
//     {
//         return std::make_shared<Banana>();
//     }
//     private:
// };

//抽象工厂模式
class Fruit
{
    public:
    virtual void name()=0;
    private:
};
class Apple : public Fruit
{
    private:
    public:
    void name()
    {
        std::cout<<"i am a apple!!"<<std::endl;
    }

};
class Banana:public Fruit
{
    private:
    public:
    void name()
    {
        std::cout<<"i am a banana !!"<<std::endl;
    }
};

class Animal
{
    public:
    virtual void name() =0;
};
class Lamp:public Animal
{
    public:
    void name()override
    {
        std::cout<<" 我是一只山羊！！"<<std::endl;
    }
};
class Dog:public Animal
{
    public:
    void name()override
    {
        std::cout<<" 我是一只小狗！！"<<std::endl;

    }
};
class Factory
{
    public:
    virtual std::shared_ptr<Fruit> GetFruit()=0;
    virtual std::shared_ptr<Animal> GetAnimal()=0;

};
class AnimalFactory:public Factory
{
    public:
    std::shared_ptr<Fruit> GetFruit(const std::string&name)
    {
        return std::shared_ptr<Fruit>();
    }
    std::shared_ptr<Animal> GetAnimal(const std::string&name)
    {
        if(name=="山羊")return std::make_shared<Lamp>();
        else
        return std::make_shared<Dog>();
    }
};
class FruitFactory:public Factory
{
    public:
    std::shared_ptr<Fruit> GetFruit(const std::string&name)
    {
             if(name=="苹果")
        {
            return std::make_shared<Apple>();
        }
        else
        {
            return std::make_shared<Banana>();
        }
    }
    std::shared_ptr<Animal> GetAnimal(const std::string&name)
    {
                return std::shared_ptr<Animal>();

    }
};

class FactoroyPorducter
{
    public:
    static std::shared_ptr<Factory> GetFactory(const std::string&name)
    {
        if(name=="水果")return std::make_shared<FruitFactory>();
        else
        return std::make_shared<AnimalFactory>();
    }
};
int main()
{
    // std::shared_ptr<Fruit> f=FruitFactory::create("苹果");
    // f->name();
    // f=FruitFactory::create("香蕉");
    // f->name();

    // std::shared_ptr<FruitFactory> ff(new AppleFactory());
    // std::shared_ptr<Fruit>Fruit=ff->create();
    // Fruit->name();
    // //ff=new BananaFactory();这样写不行
    // ff.reset(new BananaFactory());
    // Fruit=ff->create();
    // Fruit->name();

    std::shared_ptr<Factory> f=FactoroyPorducter::GetFactory("水果");
    std::shared_ptr<Fruit>ff=  f->GetFruit("苹果");

    return 0;
}